/* 
 * Copyright 2011 QDSS.org. All rights reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.qdss.oapi4j.util;

import java.io.IOException;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.qdss.oapi4j.ApiException;
import org.qdss.oapi4j.Result;
import org.qdss.oapi4j.UnauthorizedException;
import org.qdss.oapi4j.apis.paipai.PaipaiResult;
import org.qdss.oapi4j.base.BadResultException;

/**
 * Api相关工具方法
 * 
 * @author <a href="mailto:zhaofang123@gmail.com">Zhao Fangfang</a>
 * @date 2011-3-20
 * @version $Id: ApiUtils.java 41 2011-12-23 08:01:06Z zhaofang123@gmail.com $
 */
public class ApiUtils {

	public static final String ENCODING_UTF8 = "UTF-8";
	public static final String ENCODING_GBK = "GBK";
	public static final String ENCODING_DEFAULT = ENCODING_UTF8;

	private static final FastSAXReader FAST_SAX_READER = new FastSAXReader(10);
	
	/**
	 * BASE64编码
	 * 
	 * @param source
	 * @return
	 */
	public static String encodeBase64(Object source) {
		if (source == null) {
			return StringUtils.EMPTY;
		}
		
		String result = source.toString();
		try {
			result = new String(
					Base64.encodeBase64(result.getBytes(ENCODING_DEFAULT)));
		} catch (IOException e) {
			result = StringUtils.EMPTY;
		}
		return result;
	}
	
	/**
	 * BASE64解码
	 * 
	 * @param source
	 * @return
	 */
	public static String decodeBase64(Object source) {
		if (source == null) {
			return StringUtils.EMPTY;
		}
		
		String result = source.toString();
		try {
			result = new String(
					Base64.decodeBase64(result.getBytes(ENCODING_DEFAULT)));
		} catch (IOException e) {
			result = StringUtils.EMPTY;
		}
		return result;
	}
	
	/**
	 * URL编码
	 * 
	 * @param source
	 * @return
	 */
	public static String encodeURL(Object source) {
		if (source == null) {
			return StringUtils.EMPTY;
		}
		String result = source.toString();
		try {
			result = URLEncoder.encode(result, ENCODING_DEFAULT);
		} catch (IOException ex) {
			result = StringUtils.EMPTY;
		}
		return result;
	}

	/**
	 * URL解码
	 * 
	 * @param source
	 * @return
	 */
	public static String decodeURL(Object source) {
		if (source == null) {
			return StringUtils.EMPTY;
		}
		String result = source.toString();
		try {
			result = URLDecoder.decode(result, ENCODING_DEFAULT);
		} catch (IOException ex) {
			result = StringUtils.EMPTY;
		}
		return result;
	}
	
	/**
	 * 抛出异常，如果需要
	 * 
	 * @param result
	 * @throws UnauthorizedException
	 * @throws BadResultException
	 * @throws ApiException
	 */
	public static void throwIfError(Result<?> result)
			throws UnauthorizedException, BadResultException, ApiException {
		if (!result.hasError()) {
			return;
		}
		
		String error = result.getError();
		if (result instanceof PaipaiResult<?>) {
			if (error.startsWith("752") || error.startsWith("765")
					|| error.startsWith("766")) {
				throw new UnauthorizedException("POP_ERR:" + error.substring(0, 3));
			}
		}
		throw new ApiException(error);
	}

	/**
	 * 格式化 XML
	 * 
	 * @param node
	 * @return
	 * @throws RuntimeException
	 */
	public static String formatPrettyXml(Node node) throws RuntimeException {
		StringWriter out = new StringWriter();
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter writer = new XMLWriter(out, format);
		try {
			writer.write(node);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				writer.close();
			} catch (IOException e) {
			}
		}
		return out.toString();
	}
	
	/**
	 * @return
	 */
	public static FastSAXReader getFastSAXReader() {
		return FAST_SAX_READER;
	}

	/**
	 * 计算分页大小
	 * 
	 * @param total
	 * @param size
	 * @return
	 */
	public static int calcPagingSize(int total, int size) {
		return (total + size - 1) / size;
	}
}
